#ifndef VEC3
#define VEC3

#define _USE_MATH_DEFINES
#include <cmath>

template <class T>
class Vec3
{
public:
	Vec3()
	{
		m_x = 0;
		m_y = 0;
		m_z = 0;
	}

	Vec3(T x, T y, T z)
	{
		m_x = x;
		m_y = y;
		m_z = z;
	}

	Vec3& operator+=(const Vec3& rhs)
	{
		m_x += rhs.m_x;
		m_y += rhs.m_y;
		m_z += rhs.m_z;
		return *this;
	}

	Vec3& operator-=(const Vec3& rhs)
	{
		m_x -= rhs.m_x;
		m_y -= rhs.m_y;
		m_z -= rhs.m_z;
		return *this;
	}

	Vec3& operator*=(float f)
	{
		m_x *= f;
		m_y *= f;
		m_z *= f;
		return *this;
	}

	bool operator==(const Vec3& rhs)
	{
		return (m_x == rhs.GetX() && m_y == rhs.GetY() && m_z == rhs.GetZ());
	}


	T GetX() const
	{
		return m_x;
	}

	T GetY() const
	{
		return m_y;
	}

	T GetZ() const
	{
		return m_z;
	}

	void SetX(T x)
	{
		m_x = x;
	}

	void SetY(T y)
	{
		m_y = y;
	}

	void SetZ(T z)
	{
		m_z = z;
	}


private:
	T m_x;
	T m_y;
	T m_z;
};

template <class T>
Vec3<T> operator+(const Vec3<T>& a, const Vec3<T>& b)
{
	Vec3<T> result = a;
	result += b;
	return result;
}

template <class T>
Vec3<T> operator-(const Vec3<T>& a, const Vec3<T>& b)
{
	Vec3<T> result = a;
	result -= b;
	return result;
}

template <class T>
Vec3<T> operator*(const Vec3<T>& a, float f)
{
	Vec3<T> result = a;
	result *= f;
	return result;
}

typedef Vec3<int> Vec3i;
typedef Vec3<float> Vec3f;

namespace math
{
	static float degToRad(const float a)
	{
		return (a / 3.14f/*M_PI*/ * 180);
	}

	static float radToDeg(const float a)
	{
		return (a / 180 * 3.14f/*M_PI*/);
	}
};

#endif